package com.ztgf.message.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.ztgf.common.utils.CustomizeUtil;
import com.ztgf.common.utils.StrUtils;
import com.ztgf.db.utils.RedisUtil;
import com.ztgf.message.common.config.YmlConfig;
import com.ztgf.message.mapper.MessageAnnouncementMapper;
import com.ztgf.message.model.bo.MessageAnnouncementBO;
import com.ztgf.message.model.bo.MessageAnnouncementSaveBO;
import com.ztgf.message.model.dto.MessageAnnouncementDTO;
import com.ztgf.message.model.enums.MessageEnum;
import com.ztgf.message.model.service.IMessageAnnouncementService;
import com.ztgf.message.model.vo.MessageAnnouncementPageVO;
import com.ztgf.shopping.models.dto.shop.ShopInfoDTO;
import com.ztgf.shopping.models.service.shop.IShopInfoService;
import com.ztgf.sys.models.dto.SysUserDTO;
import com.ztgf.sys.models.service.ISysUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 通知消息控制器
 *
 * @author YUE
 * @Date 2020-05-28 16:20:54
 */
@DubboService
public class MessageAnnouncementServiceImpl extends ServiceImpl<MessageAnnouncementMapper, MessageAnnouncementDTO> implements IMessageAnnouncementService {

    @Resource
    private YmlConfig ymlConfig;

    @Autowired
    private MessageAnnouncementMapper messageAnnouncementMapper;

    @Autowired
    private RedisUtil redisUtil;

    @DubboReference
    private IShopInfoService shopInfoService;

    @DubboReference
    private ISysUserService sysUserService;


    @Override
    public boolean add(MessageAnnouncementSaveBO saveBO) {
        MessageAnnouncementDTO dto = new MessageAnnouncementDTO();
        BeanUtils.copyProperties(saveBO, dto);
        Long id = ymlConfig.getPkId();
        dto.setId(id);
        return this.insert(dto);
    }

    @Override
    public boolean insertAllShopsMessage(MessageAnnouncementBO bo, String sessionId) {
        SysUserDTO sysUserDTO = sysUserService.getUserBySessionId(sessionId);
        Wrapper<ShopInfoDTO> wrapper = new EntityWrapper<>();
        Integer publicType = bo.getPublicType();
        int shopType = 0;
        //发布类型 0全部用户 1全部店铺 2全部旗舰店 3全部专卖店 4全部专营店 5全部买家 6自定义
        if (publicType == 0) {
            shopType = MessageEnum.SHOP_TYPE_1.getCode();
        }
        if (publicType == 1) {
            wrapper.eq("merchant_type", 1);//卖家
            shopType = MessageEnum.SHOP_TYPE_2.getCode();
        }
        if (publicType == 2) {
            wrapper.eq("merchant_type", 1);//卖家
            wrapper.eq("type", 2);//旗舰店
            shopType = MessageEnum.SHOP_TYPE_2.getCode();
        }
        if (publicType == 3) {
            wrapper.eq("merchant_type", 1);//卖家
            wrapper.eq("type", 1);//专卖店
            shopType = MessageEnum.SHOP_TYPE_2.getCode();
        }
        if (publicType == 4) {
            wrapper.eq("merchant_type", 1);//卖家
            wrapper.eq("type", 0);//专营店
            shopType = MessageEnum.SHOP_TYPE_2.getCode();
        }
        if (publicType == 5) {
            shopType = MessageEnum.SHOP_TYPE_1.getCode();
        }
        if (publicType == 6) {
            wrapper.in("id", Arrays.asList(bo.getShopIds().split(",")));
            shopType = bo.getShopType();
        }
        List<ShopInfoDTO> shopInfoDTOS = shopInfoService.selectList(wrapper);
        Long gpId = ymlConfig.getPkId();
        for (ShopInfoDTO shopInfoDTO : shopInfoDTOS) {
            Long shopId = shopInfoDTO.getId();
            MessageAnnouncementSaveBO messageAnnouncementSaveBO = new MessageAnnouncementSaveBO();
            messageAnnouncementSaveBO.setType(MessageEnum.SERVER_MESSAGE.getCode());
            messageAnnouncementSaveBO.setShopId(shopId);
            messageAnnouncementSaveBO.setTitle(bo.getTitle());
            messageAnnouncementSaveBO.setContent(bo.getContent());
            messageAnnouncementSaveBO.setTextType(2);
            messageAnnouncementSaveBO.setJumpType(MessageEnum.MESSAGE_SHOW.getCode() + "");
            messageAnnouncementSaveBO.setShopType(shopType);
            messageAnnouncementSaveBO.setKey(shopId + "");
            messageAnnouncementSaveBO.setSendId(sysUserDTO.getId());
            messageAnnouncementSaveBO.setSendName(sysUserDTO.getName());
            messageAnnouncementSaveBO.setCompanyName(shopInfoDTO.getShopName());
            MessageAnnouncementDTO dto = new MessageAnnouncementDTO();
            BeanUtils.copyProperties(messageAnnouncementSaveBO, dto);
            Long id = ymlConfig.getPkId();
            dto.setId(id);
            dto.setGpId(gpId);
            dto.setSendTo(publicType.toString());
            this.insert(dto);
            updateUnreadMessageNum(shopId, shopType, 0);
        }
        return true;
    }

    /**
     * 获取未读消息数量
     *
     * @param shopId
     * @param type   1买家 2卖家
     * @return
     */
    @Override
    public Integer getUnreadMessageNum(Long shopId, int type) {
        return baseMapper.getUnreadMessageNum(shopId, type);
    }

    /**
     * 更新缓存未读消息数量
     *
     * @param shopId
     * @param type   1买家 2卖家
     * @return
     */
    @Override
    public Integer updateUnreadMessageNum(Long shopId, int type, int updateNum) {
        Integer unreadMessageNum = getUnreadMessageNum(shopId, type) - updateNum;
        redisUtil.set("getUnreadMessageNum::" + shopId + "-" + type, unreadMessageNum);
        return unreadMessageNum;
    }

    /**
     * 获取未读消息
     *
     * @param shopId
     * @param type   1买家 2卖家
     * @return
     */
    @Override
    public List<MessageAnnouncementDTO> getUnreadMessage(Long shopId, int type) {
        MessageAnnouncementBO messageAnnouncementBO = new MessageAnnouncementBO();
        messageAnnouncementBO = addMustData(messageAnnouncementBO);
        messageAnnouncementBO.setShopId(shopId);
        messageAnnouncementBO.setShopType(type);
        Wrapper<MessageAnnouncementDTO> wrapper = getBySelectMessageInfo(messageAnnouncementBO);
        wrapper.eq("status", MessageEnum.UNREAD_MESSAGE.getCode());
        return selectList(wrapper);
    }

    /**
     * 更新消息状态
     *
     * @return
     */
    @Override
    public boolean updateMessageStatusById(Long id) {
        MessageAnnouncementDTO messageAnnouncementDTO = messageAnnouncementMapper.selectById(id);
        messageAnnouncementDTO.setStatus(MessageEnum.READ_MESSAGE.getCode());
        messageAnnouncementMapper.updateById(messageAnnouncementDTO);
        updateUnreadMessageNum(messageAnnouncementDTO.getShopId(), messageAnnouncementDTO.getShopType(), 0);//更新缓存消息
        return true;
    }

    /**
     * 批量更新 已读
     *
     * @param shopId
     * @param shopId
     * @return
     */
    @Override
    public boolean updateAllMessageStatusByIds(Long shopId, Integer type, Integer shopType) {
        Wrapper wrapper = new EntityWrapper();
        MessageAnnouncementDTO messageAnnouncementDTO = new MessageAnnouncementDTO();
        messageAnnouncementDTO.setStatus(MessageEnum.READ_MESSAGE.getCode());
        wrapper.eq("shop_id", shopId);
        wrapper.eq("type", type);
        wrapper.eq("shop_type", shopType);
        messageAnnouncementMapper.update(messageAnnouncementDTO, wrapper);
        updateUnreadMessageNum(shopId, shopType, 0);//更新缓存消息
        return true;
    }

    /**
     * 批量删除 已读
     *
     * @param shopId
     * @param shopId
     * @return
     */
    @Override
    public boolean deleteAllMessageStatusByIds(Long shopId, Integer type, Integer shopType) {
        Wrapper wrapper = new EntityWrapper();
        MessageAnnouncementDTO messageAnnouncementDTO = new MessageAnnouncementDTO();
        messageAnnouncementDTO.setDeleted(1);
        wrapper.eq("shop_id", shopId);
        wrapper.eq("type", type);
        wrapper.eq("shop_type", shopType);
        wrapper.eq("status", MessageEnum.READ_MESSAGE.getCode());
        messageAnnouncementMapper.update(messageAnnouncementDTO, wrapper);
        return true;
    }

    /**
     * 删除选中消息
     *
     * @param id
     * @return
     */
    @Transactional
    @Override
    public boolean deleteSelectMessageById(Long id) {
        MessageAnnouncementDTO messageAnnouncementDTO = selectById(id);
        boolean b = deleteById(id);
        if (b) {
            updateUnreadMessageNum(messageAnnouncementDTO.getShopId(), messageAnnouncementDTO.getShopType(), 0);
            return true;
        }
        return false;
    }

    /**
     * 逻辑删除
     *
     * @param ids
     * @return
     */
    @Override
    public boolean deleteLogicById(String ids) {
        String[] idList = ids.split(",");
        for (String s : idList) {
            MessageAnnouncementDTO messageAnnouncementDTO = selectById(Long.parseLong(s));
            messageAnnouncementDTO.setDeleted(1);
            updateById(messageAnnouncementDTO);
        }
        return true;
    }

    @Override
    public Page<MessageAnnouncementPageVO> queryAdminPageList(MessageAnnouncementBO bo) {
        Page<MessageAnnouncementPageVO> page = new Page<>(bo.getPageNo(), bo.getPageSize());
        List<MessageAnnouncementPageVO> list = baseMapper.queryAdminPageList(page, bo);
        if (CustomizeUtil.listIsNull(list)) {
            return page;
        }
        for (MessageAnnouncementPageVO messageAnnouncementPageVO : list) {
            String sendObject = this.getSendObject(messageAnnouncementPageVO.getSendTo(), messageAnnouncementPageVO.getGpId());
            messageAnnouncementPageVO.setCompanyName(sendObject);
        }
        page.setRecords(list);
        return page;
    }

    /**
     * @return : java.lang.String
     * @Author :chenyu.wang
     * @Description : 获取接收对象
     * @Date : 2021.03.10 11:05
     * @Param : [s]
     **/
    private String getSendObject(String s, Long gpId) {
        String obj = "";
        int i = Integer.parseInt(s);
        switch (i) {
            case 0:
                obj = "全部用户";
                break;
            case 1:
                obj = "全部店铺";
                break;
            case 2:
                obj = "全部旗舰店";
                break;
            case 3:
                obj = "全部专卖店";
                break;
            case 4:
                obj = "全部专营店";
                break;
            case 5:
                obj = "全部买家";
                break;
            case 6:
                obj = this.getAutoShop(gpId);
                break;
            default:
                break;
        }
        return obj;
    }

    /**
     * @return : java.lang.String
     * @Author :chenyu.wang
     * @Description : 获取自定义接收对象的公司名称
     * @Date : 2021.03.10 11:16
     * @Param : [gpId]
     **/
    private String getAutoShop(Long gpId) {
        Wrapper<MessageAnnouncementDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("gp_id", gpId);
        List<MessageAnnouncementDTO> list = this.selectList(wrapper);
        if (CustomizeUtil.listIsNull(list)) {
            return "";
        }
        List<String> names = new ArrayList<>();
        for (MessageAnnouncementDTO dto : list) {
            // 查询店铺公司名称
            ShopInfoDTO shopInfoDTO = shopInfoService.selectById(dto.getShopId());
            names.add(shopInfoDTO.getName());
        }
        return Joiner.on(",").join(names);
    }

    /**
     * 物理删除
     *
     * @param id
     * @return
     */
    public boolean deletePhById(Long id) {
        return deleteById(id);
    }

    /**
     * 消息恢复
     *
     * @param id
     * @return
     */
    @Override
    public boolean recoverPhById(Long id) {
        MessageAnnouncementDTO messageAnnouncementDTO = new MessageAnnouncementDTO();
        messageAnnouncementDTO.setId(id);
        messageAnnouncementDTO.setDeleted(0);
        messageAnnouncementMapper.updateById(messageAnnouncementDTO);
        return true;
    }

    /**
     * 根据相关信息查找 消息 有页码
     *
     * @param messageAnnouncementBO
     * @return
     */
    @Override
    public Page<MessageAnnouncementDTO> getBySelectBannerInfoPage(MessageAnnouncementBO messageAnnouncementBO) {
        messageAnnouncementBO = addMustData(messageAnnouncementBO);
        Wrapper<MessageAnnouncementDTO> wrapper = getBySelectMessageInfo(messageAnnouncementBO);
        return selectPage(new Page<>(messageAnnouncementBO.getPageNo(), messageAnnouncementBO.getPageSize()), wrapper);
    }

    /**
     * 根据相关信息查找 消息 有页码
     *
     * @param messageAnnouncementBO
     * @return
     */
    @Override
    public Page<MessageAnnouncementDTO> getBySelectPublicMessageInfoPage(MessageAnnouncementBO messageAnnouncementBO) {
        messageAnnouncementBO = addMustData(messageAnnouncementBO);
        Wrapper<MessageAnnouncementDTO> wrapper = getBySelectPublicMessageInfo(messageAnnouncementBO);
        return selectPage(new Page<>(messageAnnouncementBO.getPageNo(), messageAnnouncementBO.getPageSize()), wrapper);
    }

    /**
     * 添加必要数据
     *
     * @param messageAnnouncementBO
     * @return
     */
    private MessageAnnouncementBO addMustData(MessageAnnouncementBO messageAnnouncementBO) {
        return messageAnnouncementBO;
    }

    private Wrapper<MessageAnnouncementDTO> getBySelectMessageInfo(MessageAnnouncementBO messageAnnouncementBO) {
        Wrapper<MessageAnnouncementDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("shop_id", messageAnnouncementBO.getShopId());
        wrapper.eq("shop_type", messageAnnouncementBO.getShopType());
        wrapper.orderBy("status", true);//未读在前
        wrapper.orderBy("create_time", false);//时间降序
        if (null != messageAnnouncementBO.getType()) {
            wrapper.eq("type", messageAnnouncementBO.getType());
        }
        wrapper.eq("deleted", "0");//查找未删除消息
        return wrapper;
    }

    private Wrapper<MessageAnnouncementDTO> getBySelectPublicMessageInfo(MessageAnnouncementBO messageAnnouncementBO) {
        Wrapper<MessageAnnouncementDTO> wrapper = new EntityWrapper<>();
        if (StrUtils.isNotEmpty(messageAnnouncementBO.getTitle())) {//标题搜索
            wrapper.like("title", messageAnnouncementBO.getTitle());
        }
        if (null != messageAnnouncementBO.getSendId()) {//发送人
            wrapper.eq("send_id", messageAnnouncementBO.getSendId());
        }
        if (StrUtils.isNotEmpty(messageAnnouncementBO.getStartDate()) && StrUtils.isNotEmpty(messageAnnouncementBO.getEndDate())) {
            wrapper.ge("create_time", messageAnnouncementBO.getStartDate());
            wrapper.le("create_time", messageAnnouncementBO.getEndDate());
        }
        //wrapper.eq("shop_type", messageAnnouncementBO.getShopType());
        wrapper.isNotNull("send_id");
        wrapper.eq("type", messageAnnouncementBO.getType());
        wrapper.eq("deleted", "0");//查找未删除消息
        wrapper.orderBy("create_time", false);//时间降序
        return wrapper;
    }
}
